package service

import (
	"context"
	"errors"
	"github.com/kuangshp/go-utils/k"
	"github.com/spf13/cast"
	"insighttracking/common/enum"
	"insighttracking/common/utils"
	"insighttracking/query/bo"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"strings"
)

type _ordersService struct{}

func (s _ordersService) GetByIdApi(ctx context.Context, id int64) (*model.OrdersEntity, error) {
	return dao.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.ID.Eq(id)).First()
}

func (s _ordersService) ModifyStatusByIdApi(ctx context.Context, tx *dao.QueryTx, idList []int64, status int64) error {
	if tx == nil {
		if _, err := dao.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.ID.In(idList...)).UpdateSimple(
			dao.OrdersEntity.Status.Value(status),
		); err != nil {
			return err
		}
	} else {
		if _, err := tx.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.ID.In(idList...)).UpdateSimple(
			dao.OrdersEntity.Status.Value(status),
		); err != nil {
			return err
		}
	}

	return nil
}

func (s _ordersService) CreateApi(ctx context.Context, tx *dao.QueryTx, modal *model.OrdersEntity) error {
	if err := tx.OrdersEntity.WithContext(ctx).Create(modal); err != nil {
		return err
	}
	return nil
}

func (s _ordersService) GetDetailByIdApi(ctx context.Context, id int64) (ordersBo bo.OrdersBo, err error) {
	err = dao.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.ID.Eq(id)).
		Select(
			dao.OrdersEntity.ALL,
			dao.EnterpriseCustomerEntity.Name.As("CustomerName"),
		).
		LeftJoin(dao.EnterpriseCustomerEntity, dao.EnterpriseCustomerEntity.ID.EqCol(dao.OrdersEntity.CustomerID)).
		Order(dao.OrdersEntity.ID.Desc()).
		Scan(&ordersBo)
	return
}

func (s _ordersService) GetPageApi(ctx context.Context, req bo.OrdersPageBoReq) (ordersBo []*bo.OrdersBo, count int64, err error) {
	tx := dao.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.EnterpriseID.Eq(req.EnterpriseID))
	if req.OrderNo != "" {
		tx = tx.Where(dao.OrdersEntity.OrderNo.Eq(req.OrderNo))
	}
	if req.Status != "" {
		tx = tx.Where(dao.OrdersEntity.Status.Eq(cast.ToInt64(req.Status)))
	}
	if req.StartDate != "" && req.EndDate != "" {
		tx = tx.Where(dao.OrdersEntity.CreatedAt.Between(utils.DateTimeStrToTime(req.StartDate), utils.DateTimeStrToTime(req.EndDate)))
	}
	if req.GoodsDateStartDate != "" && req.GoodsDateEndDate != "" {
		tx = tx.Where(dao.OrdersEntity.SendGoodsDate.Between(utils.DateTimeStrToTime(req.GoodsDateStartDate), utils.DateTimeStrToTime(req.GoodsDateEndDate)))
	}
	if req.WaitProduction == 1 {
		tx = tx.Where(dao.OrdersEntity.IsProduction.Eq(0))
	}
	// 传递的客户
	if req.CustomerId != "" {
		tx = tx.Where(dao.OrdersEntity.CustomerID.Eq(cast.ToInt64(req.CustomerId)))
	}
	if len(req.StatusList) > 0 {
		tx = tx.Where(dao.OrdersEntity.Status.In(req.StatusList...))
	}
	if req.Name != "" {
		req.Name = strings.ReplaceAll(req.Name, "%", "\\%")
		req.Name = strings.ReplaceAll(req.Name, "_", "\\%")
		detailEntities, err := dao.OrdersDetailEntity.WithContext(ctx).Where(dao.OrdersDetailEntity.SnapshotName.Like("%" + req.Name + "%")).Find()
		if err != nil || len(detailEntities) == 0 {
			return nil, 0, errors.New("查无数据")
		}
		orderIdList := k.Map(detailEntities, func(item *model.OrdersDetailEntity, index int) int64 {
			return item.OrdersID
		})
		tx = tx.Where(dao.OrdersEntity.ID.In(orderIdList...))
	}
	if req.CustomerName != "" {
		req.CustomerName = strings.ReplaceAll(req.CustomerName, "%", "\\%")
		req.CustomerName = strings.ReplaceAll(req.CustomerName, "_", "\\%")
		customerEntities, err := dao.EnterpriseCustomerEntity.WithContext(ctx).Where(dao.EnterpriseCustomerEntity.Name.Like("%" + req.CustomerName + "%")).Find()
		if err != nil || len(customerEntities) == 0 {
			return nil, 0, errors.New("查无数据")
		}
		customerIdList := k.Map(customerEntities, func(item *model.EnterpriseCustomerEntity, index int) int64 {
			return item.ID
		})
		tx = tx.Where(dao.OrdersEntity.CustomerID.In(customerIdList...))
	}
	if req.SettlementStatus != "" {
		tx = tx.Where(dao.OrdersEntity.SettlementStatus.Eq(cast.ToInt64(req.SettlementStatus)))
	}
	offset, limit := utils.DbPage(req.PageNumber, req.PageSize)
	count, err = tx.
		Select(
			dao.OrdersEntity.ALL,
			dao.EnterpriseCustomerEntity.Name.As("CustomerName"),
			dao.WarehouseEntity.Name.As("WarehouseName"),
			dao.EnterprisePersonEntity.Name.As("PurchaserName"),
		).
		LeftJoin(dao.EnterpriseCustomerEntity, dao.EnterpriseCustomerEntity.ID.EqCol(dao.OrdersEntity.CustomerID)).
		LeftJoin(dao.WarehouseEntity, dao.WarehouseEntity.ID.EqCol(dao.OrdersEntity.WarehouseID)).
		LeftJoin(dao.EnterprisePersonEntity, dao.EnterprisePersonEntity.ID.EqCol(dao.OrdersEntity.PurchaserID)).
		Order(dao.OrdersEntity.ID.Desc()).
		ScanByPage(&ordersBo, offset, limit)
	return
}

func (s _ordersService) GetSendGoodsDateListApi(ctx context.Context, enterpriseId int64, startDate string, endDate string, warehouseID string) ([]*model.OrdersEntity, error) {
	tx := dao.OrdersEntity.WithContext(ctx).Where(
		dao.OrdersEntity.EnterpriseID.Eq(enterpriseId),
		dao.OrdersEntity.SendGoodsDate.Between(utils.DateTimeStrToTime(startDate), utils.DateTimeStrToTime(endDate)),
		dao.OrdersEntity.Status.Neq(enum.OrdersCancelEnum),
	)
	if warehouseID != "" {
		//tx = tx.Where(dao.OrdersEntity.Where(dao.OrdersEntity.WarehouseID.Eq(cast.ToInt64(warehouseID))))
	}
	return tx.Find()
}

func (s _ordersService) GetByIdListApi(ctx context.Context, enterpriseId int64, orderIdList []int64) ([]*model.OrdersEntity, error) {
	return dao.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.EnterpriseID.Eq(enterpriseId), dao.OrdersEntity.ID.In(orderIdList...)).Find()
}

func (s _ordersService) UpdateProduceStatusApi(ctx context.Context, tx *dao.QueryTx, list []int64, status int64) (err error) {
	_, err = tx.OrdersEntity.WithContext(ctx).Where(dao.OrdersEntity.ID.In(list...)).UpdateColumn(dao.OrdersEntity.IsProduction, status)
	return
}

func (s _ordersService) GetUnshippedListApi(ctx context.Context, enterpriseID int64) ([]*model.OrdersEntity, error) {
	return dao.OrdersEntity.WithContext(ctx).
		Where(dao.OrdersEntity.Status.Lt(enum.OrdersAlreadyShippedEnum), dao.OrdersEntity.EnterpriseID.Eq(enterpriseID)).Find()
}

var OrdersService = new(_ordersService)
